home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / v7n13.arc / QFN.ASM < prev    next >
Assembly Source File  |  1988-06-06  |  9KB  |  251 lines

  1.         name    qfn
  2.         title   QFN.ASM --- qualify file name
  3.         page    55,132
  4. ;
  5. ;
  6. ; QFN.ASM -- Qualify File Name
  7. ;
  8. ; Copyright (C) 1988 Ziff Davis
  9. ; by Ray Duncan Feb. 1988
  10. ;
  11. ; Call with:    DS:SI = filename address
  12. ;               AX    = length
  13. ;
  14. ; Returns:      Carry = clear if filename OK
  15. ;               DS:SI = qualified filename
  16. ;               AX    = length
  17. ;               or
  18. ;               Carry = set if bad filename
  19. ;               Registers other than DS:SI
  20. ;               and AX are preserved.
  21. ;
  22.  
  23. DGROUP  group   _DATA
  24.  
  25. _DATA   segment word public 'DATA'
  26.  
  27. cdrive  db      0               ; current drive
  28. cpath   db      '\',64 dup (0)  ; current directory
  29.  
  30. tbuff   db      64 dup (0)      ; target directory
  31.  
  32. qbuff   db      'X:\'           ; qualified pathname
  33.         db      64 dup (0)
  34.  
  35. fname   dw      ?               ; filename address
  36. flen    dw      ?               ; filename length
  37.  
  38. _DATA   ends
  39.  
  40.  
  41. _TEXT   segment word public 'CODE'
  42.  
  43.         assume  cs:_TEXT,ds:DGROUP
  44.  
  45.         public  qfn             ; make visible to Linker
  46.  
  47. qfn     proc    near            ; qualify file name
  48.  
  49.         push    bx              ; save registers        
  50.         push    cx
  51.         push    dx
  52.         push    di
  53.         push    es
  54.  
  55.         mov     flen,ax         ; save length and 
  56.         mov     fname,si        ; address of filename
  57.  
  58.         mov     ax,ds           ; make DGROUP addressable
  59.         mov     es,ax           ; with ES register
  60.  
  61.                                 ; save current drive...
  62.         mov     ah,19h          ; fxn 19h = get drive
  63.         int     21h             ; transfer to MS-DOS
  64.         mov     cdrive,al       ; save it
  65.  
  66.                                 ; save current directory...
  67.                                 ; DS:SI = buffer
  68.         mov     si,offset DGROUP:cpath+1
  69.         mov     ah,47h          ; fxn 47h = get directory
  70.         mov     dl,0            ; drive = current
  71.         int     21h             ; transfer to MS-DOS
  72.  
  73.                                 ; did caller specify drive?
  74.         mov     di,fname        ; get address of name
  75.         mov     cx,flen         ; get length of name
  76.  
  77.         cmp     cx,2            ; if drive, length must 
  78.                                 ; be >= 2 chars.
  79.         jl      qfn2            ; too short, no drive
  80.  
  81.                                 ; check for drive delimiter
  82.         cmp     byte ptr [di+1],':'
  83.         jne     qfn2            ; no delimiter, jump
  84.  
  85.         mov     dl,[di]         ; get ASCII drive code
  86.         or      dl,20h          ; fold to lower case
  87.         sub     dl,'a'          ; convert it to binary
  88.         mov     ah,0eh          ; fxn 0eh = select drive
  89.         int     21h             ; transfer to MS-DOS
  90.  
  91.                                 ; get current drive to
  92.                                 ; make sure drive selected
  93.         mov     ah,19h          ; fxn 19h = get current drive
  94.         int     21h             ; transfer to MS-DOS
  95.         cmp     dl,al           ; current = requested?
  96.         je      qfn1            ; jump if select succeeded
  97.         jmp     qfn8            ; exit, select failed
  98.  
  99. qfn1:   add     di,2            ; bump pointer past drive
  100.         sub     cx,2            ; and decrement length
  101.  
  102. qfn2:                           ; save current directory
  103.                                 ; again for new drive...
  104.                                 ; DS:SI = buffer
  105.         mov     si,offset DGROUP:cpath+1
  106.         mov     ah,47h          ; fxn 47h = get directory
  107.         mov     dl,0            ; drive = current
  108.         int     21h             ; transfer to MS-DOS
  109.  
  110.                                 ; scan off path if any
  111.         push    di              ; save start of path
  112.         mov     al,'\'          ; path delimiter
  113.  
  114. qfn3:   mov     fname,di        ; save path pointer
  115.         mov     flen,cx         ; save path length
  116.         jcxz    qfn4            ; jump if none left
  117.  
  118.         repne scasb             ; any '\' left in path?
  119.         je      qfn3            ; loop if '\' found
  120.  
  121. qfn4:   pop     si              ; recover starting address
  122.                                 ; of path portion
  123.  
  124.                                 ; copy path to local buffer
  125.                                 ; and make it ASCIIZ...
  126.         mov     di,offset DGROUP:tbuff
  127.         mov     cx,fname        ; calculate path length
  128.         sub     cx,si
  129.         jz      qfn6            ; jump, no path at all
  130.         cmp     cx,1            ; root directory?
  131.         je      qfn5            ; jump if root
  132.         dec     cx              ; else discard last '\'
  133.  
  134. qfn5:   rep movsb               ; transfer path and
  135.         xor     al,al           ; append null byte
  136.         stosb
  137.         
  138.                                 ; now make target directory
  139.                                 ; the current directory...
  140.         mov     dx,offset DGROUP:tbuff
  141.         mov     ah,3bh          ; fxn 3BH = select directory
  142.         int     21h             ; transfer to MS-DOS
  143.         jc      qfn8            ; jump, no such directory
  144.  
  145. qfn6:                           ; build up full pathname...
  146.  
  147.         mov     ah,19h          ; get current drive
  148.         int     21h             ; transfer to MS-DOS
  149.         add     al,'A'          ; convert binary to ASCII
  150.         mov     qbuff,al        ; store ASCII drive code
  151.  
  152.                                 ; get current directory
  153.         mov     dl,0            ; DL = 0 for default drive
  154.                                 ; DS:SI = buffer address
  155.         mov     si,offset DGROUP:qbuff+3
  156.         mov     ah,47h          ; fxn 47h = get current dir
  157.         int     21h             ; transfer to MS-DOS
  158.         jc      qfn8            ; jump if error 
  159.  
  160.                                 ; point to path component
  161.         mov     di,offset DGROUP:qbuff+3
  162.         cmp     byte ptr [di],0 ; is current directory
  163.                                 ; the root directory?
  164.         je      qfn7            ; yes, jump
  165.  
  166.         xor     al,al           ; scan for null byte at
  167.         mov     cx,-1           ; end of path name
  168.         repne scasb             ; and append backslash
  169.         mov     byte ptr [di-1],'\'
  170.  
  171. qfn7:                           ; now append filename
  172.                                 ; to drive and path...
  173.         mov     si,fname        ; filename address
  174.         cmp     byte ptr [si],'.'
  175.         je      qfn8            ; exit if directory alias
  176.         mov     cx,flen         ; filename length
  177.         rep movsb               ; copy it
  178.                                         
  179.                                 ; set DS:SI = address 
  180.         mov     si,offset DGROUP:qbuff
  181.         mov     ax,di           ; and AX = length of
  182.         sub     ax,si           ; fully qualified filename
  183.  
  184.         call    makelc          ; fold filename to lower
  185.                                 ; case to make it pretty
  186.  
  187.         clc                     ; Carry = false to 
  188.                                 ; indicate success
  189.  
  190.         jmp     qfn9            ; jump to common exit
  191.  
  192. qfn8:                           ; come here if any 
  193.                                 ; error detected...
  194.  
  195.         stc                     ; Carry = true to 
  196.                                 ; indicate error
  197.  
  198. qfn9:   pushf                   ; save Carry flag
  199.         push    ax              ; save final length
  200.  
  201.                                 ; restore original directory
  202.         mov     dx,offset DGROUP:cpath
  203.         mov     ah,3bh          ; fxn 3BH = select directory
  204.         int     21h             ; transfer to MS-DOS
  205.  
  206.         mov     dl,cdrive       ; restore original drive
  207.         mov     ah,0eh          ; fxn 0EH = set drive
  208.         int     21h             ; transfer to MS-DOS
  209.  
  210.         pop     ax              ; restore length
  211.         popf                    ; and Carry flag
  212.  
  213.         pop     es              ; restore other affected
  214.         pop     di              ; registers
  215.         pop     dx
  216.         pop     cx
  217.         pop     bx
  218.  
  219.         ret                     ; back to caller
  220.  
  221. qfn     endp
  222.  
  223.  
  224. makelc  proc    near            ; string -> lower case
  225.                                 ; DS:SI = address
  226.                                 ; AX = length
  227.  
  228.         push    bx              ; save BX contents
  229.         xor     bx,bx           ; BX will be pointer
  230.  
  231. mlc1:                           ; change A-Z to a-z
  232.         cmp     byte ptr [bx+si],'A'
  233.         jb      mlc2
  234.         cmp     byte ptr [bx+si],'Z'
  235.         ja      mlc2
  236.         or      byte ptr [bx+si],20h
  237.  
  238. mlc2:   inc     bx              ; advance through string
  239.         cmp     bx,ax           ; done with string yet?
  240.         jne     mlc1            ; no, check next char.
  241.  
  242.         pop     bx              ; restore BX and
  243.         ret                     ; return to caller
  244.  
  245. makelc  endp
  246.  
  247. _TEXT   ends
  248.  
  249.         end
  250.